# -*- coding: UTF-8 -*-
"""
@author:zhangxing
@file:selenium_middlewares.py
"""
import os
import random
import sys
import time

from scrapy import Selector
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from commonresources.inner_utils.ip_proxy_utils import get_single_ip
from commonresources.third_middlewares import user_agent_list


class SeleniumUtils:
    def __init__(self,
                 url=None,
                 max_window=True, #全屏
                 slide_bottom=10000, #滑动条拉满
                 next_page_button_xpath=None,
                 ip_proxy=False,
                 headless=True,
                 close_picture=False):
        self.headless = headless #无头
        self.ip_proxy = ip_proxy
        self.max_window = max_window
        self.slide_bottom = slide_bottom
        self.close_picture = close_picture   #无图模式
        self.next_page_button_xpath = next_page_button_xpath
        self.page_source = ''
        self._init = 0
        # self.driver = ""
        if sys.platform.startswith('win'):  #根据系统版本选择要使用的驱动器
            self.chromedriver_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                  "driver", "chromedriver.exe")
        else:
            self.chromedriver_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                  "driver", "chromedriver")
        self.init_driver(url, self.max_window, self.slide_bottom, self.close_picture)#调用下面的init_driver函数

    def init_driver(self, url, max_window, slide_bottom, headless=None, ip_proxy=None, chromedriver_path=None):
        try:
            self.close()  # 是否关闭之前的页面
        except Exception as e:
            pass
        headless = self.headless if not headless else headless
        ip_proxy = self.ip_proxy if not ip_proxy else ip_proxy
        chromedriver_path = self.chromedriver_path if not chromedriver_path else chromedriver_path

        random_ua = random.choice(user_agent_list)#选取随机ua头
        options = webdriver.ChromeOptions()#配置 chrome 启动属性的类，实例化一下
        options.add_argument(f"User-Agent='{random_ua}'")
        if self.close_picture:
            options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})#以下皆为配置启动属性的参数
        # options.add_experimental_option('excludeSwitches', ['enable-automation'])
        if headless:
            options.add_argument('--headless')  #添加无头参数
        if ip_proxy:
            options.add_argument(f"--proxy-server={get_single_ip()}")
        self.driver = webdriver.Chrome(options=options, executable_path=chromedriver_path)
        if url:
            self.get_new_url_page(url, max_window, slide_bottom)

    def get_proper_page(self, click_xpaths_list, ):#页面连续点击操作
        for click_xpath in click_xpaths_list:
            self.driver.find_element_by_xpath(click_xpath).click()
            time.sleep(1)

        return self.get_scrapy_selector()


    def get_new_url_page(self, new_url, max_window, slide_bottom, wait_element_xpath=None):
        self.driver.get(new_url)
        self.wait(wait_element_xpath)
        if max_window:
            self.driver.maximize_window() # 浏览器窗口最大化
        if not slide_bottom:
            slide_bottom = self.slide_bottom
        js = f"var q=document.documentElement.scrollTop={slide_bottom}"
        self.driver.execute_script(js)
        return self.get_scrapy_selector()

    def get_scrapy_selector(self):#把页面转换成能用xpath的对象
        if self._init:
            _page_source = self.driver.page_source
            self.page_source = _page_source if (_page_source != self.page_source or self.page_source == '') else ''
            return Selector(text=self.page_source)
        else:
            self._init = 1

    def handle_next_page(self, next_page_button_xpath, wait_element_xpath=None):#翻页操作
        next_page_button_xpath = self.next_page_button_xpath if not next_page_button_xpath else next_page_button_xpath
        self.wait(wait_element_xpath)
        # if "input" in next_page_button_xpath or 'button' in next_page_button_xpath:
        # WebDriverWait(self.driver, 5).until(EC.element_to_be_clickable((By.XPATH, next_page_button_xpath))).click()
        # else:
        click_element = self.driver.find_element_by_xpath(next_page_button_xpath)  #通过xpath找到，翻页的节点
        click_element.click()
        return self.get_scrapy_selector()

    def get_current_url(self, next_page_button_xpath, wait_element_xpath=None,need_kill=False):#可以获取点击后页面的url
        next_page_button_xpath = self.next_page_button_xpath if not next_page_button_xpath else next_page_button_xpath
        self.wait(wait_element_xpath)
        click_element = self.driver.find_element_by_xpath(next_page_button_xpath)  #通过xpath找到，翻页的节点
        click_element.click()
        if need_kill:
            windows = self.driver.window_handles  #对于会打开新页面的网页，可以切换到新的页面
            self.driver.switch_to.window(windows[-1])
            current_url = self.driver.current_url
            time.sleep(2)
            self.driver.close()
            self.driver.switch_to.window(windows[0])
        else:
            time.sleep(2)
            current_url = self.driver.current_url
        return  current_url


    def wait(self, wait_element_xpath, wait_less=None):  #等待页面加载完成，不用主动调用，在翻页操作函数里有
        if wait_element_xpath:
            WebDriverWait(self.driver, 4, poll_frequency=0.3).until(
                EC.presence_of_element_located((By.XPATH, wait_element_xpath)))
        elif wait_less:
            time.sleep(3)
        else:
            time.sleep(3)

    def input(self,input_xpath_dict,click_xpath,need_click=False):#输入一个字典，会在指定的xpath输入对应的内容,自定义是否有点击按钮
        for input_xpath in input_xpath_dict.items():
            ele = self.driver.find_element_by_xpath(input_xpath[0])  # 找到id为XXX的节点
            ele.send_keys(input_xpath[1]) #往该节点输入内容
        if need_click ==True:
            click_element = self.driver.find_element_by_xpath(click_xpath)  # 通过xpath找到，刷新内容
            click_element.click()

    def back(self):
        time.sleep(2)
        self.driver.back()


    def close(self):
        self.driver.close()
        self.driver.quit()
